﻿<documents created="2010-12-15 11:41:51Z"><document src="C:\Users\Anders\Documents\automatones\Visual Studio\AutomaTones\AutomaTones\Model\Automaton Model\RuleLib\WolframAutomata.cs" renderPrefix="s0"><chunk hits="-1" domain="unknown"><source><![CDATA[using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using Microsoft.Pex.Framework;

namespace AutomaTones.Model.Automaton_Model.RuleLib {
    /// <author>Anders Øland / anoe@itu</author>
    /// <summary>
    /// Provides the rule used for the Wolfram Automatons - or any other pattern-based rule-type cellular automaton.
    /// <br></br><br></br>
    /// This class also facilitates easy setup of Wolfram/pattern-based CA. 
    /// </summary>
    [PexClass]
    public static partial class WolframAutomata {
        /// <summary>
        /// This rule is intended for use with Wolfram one-dimensional automata -
        /// or any other pattern-based rule-type cellular automaton.
        /// The state space may have any size - but MUST be shared by all cells, and the lower bound MUST be zero - 
        /// and the grid can be N-dimensional.
        /// <br></br><br></br>
        /// The rule is represented by a Wolfram code; 
        /// range 0 to S^S^(2n+1) - 1 where S = size of the state space, n = size of the neighbourhood.
        /// Eg. a Wolfram Code for a binary rule based on two neighbours:<br></br>
        /// Pattern 1: 00 --> new state 0<br></br>
        /// Pattern 2: 01 --> new state 1<br></br>
        /// Pattern 3: 10 --> new state 0<br></br>
        /// Pattern 4: 11 --> new state 1<br></br>
        /// The code number is the binary number formed by the state column: %1010
        /// ==> Rule number 10 (decimal). <br></br><br></br>
        /// Thus when eg. pattern 4 is parsed to this rule ==> it returns bit 4 of the Wolfram code.<br></br><br></br>
        /// NOTE: 8 neighbours and 8 possible states ==> 8^8^17 - 1 possible rules(!!!) and ulong.MaxValue = 2^64 -1. 
        /// Thus, not all possible rules can be used!
        /// </summary>
        /// <param name="cell"></param>
        /// <param name="statesOfNeighbours"></param>
        /// <param name="wolframCode">MUST be less than 2^64</param>
        /// <returns></returns>
        public static int WolframRule(Cell cell, ref IEnumerable<Rule.StateAtCoordinate> statesOfNeighbours,
                                      int[] wolframCode) {
            Contract.Requires(null != cell);
            Contract.Requires(0 == cell.State.SpaceMin && 0 < cell.State.SpaceMax);
            Contract.Requires(Contract.ForAll(statesOfNeighbours, sn => 1 == sn.Position.Coord.Length));
            Contract.Requires(Contract.ForAll(statesOfNeighbours, sn => cell.State.SpaceMin <= sn.State
                                                                        && cell.State.SpaceMax >= sn.State));
            Contract.Ensures(cell.State.SpaceMin <= Contract.Result<int>());
            Contract.Ensures(cell.State.SpaceMax >= Contract.Result<int>());
            // Find the bit(or digit) number representing this pattern in the Wolfram Code for the chosen rule.
            var bit = Tools.Math.BaseToDecimal((from n in statesOfNeighbours select n.State).ToArray(),
                                               (uint) (cell.State.SpaceMax - cell.State.SpaceMin + 1));
            return wolframCode[bit];
        }

        /// <summary>
        /// Converts a Wolfram Code from decimal to any base( = the amount of possible states).
        /// The resulting array will have the length required to represent 2^64 - 1 in the given base.
        /// </summary>
        /// <param name="wolframCode">Decimal representation</param>
        /// <param name="stateSpace">The amount of possible states</param>
        /// <returns>Base[statespace] representation of the code by array of digits</returns>
        public static int[] WolframCode(ulong wolframCode, uint stateSpace = 2u) {
            Contract.Requires(1 < stateSpace);
            Contract.Ensures(Tools.Math.DecimalToBase(ulong.MaxValue, stateSpace).Length >=
                             Contract.Result<int[]>().Length);
            var digits = Tools.Math.DecimalToBase(ulong.MaxValue, stateSpace).Length;
            return Tools.Math.DecimalToBase(wolframCode, stateSpace, (uint) digits);
        }

        /// <summary>
        /// Converts a series of rule patterns into a Wolfram Code represented by an array of digits.
        /// The array will have the lenght needed to represent 2^64 -1 (ulong.MaxValue) in base[stateSpace]
        /// </summary>
        /// <param name="patterns">All the patterns included in the rule - concatenated in one array</param>
        /// <param name="states">List of the states which each pattern map to</param>
        /// <param name="numOfNeighbours">The size of the neighbourhood used by the intended rule</param>
        /// <param name="stateSpace">Amount of possible states</param>
        /// <returns>Base[statespace] representation of the code by array of digits</returns>
        public static int[] WolframCode(int[] patterns, int[] states, uint numOfNeighbours = 3u, uint stateSpace = 2u) {
            Contract.Requires(1 < stateSpace);
            Contract.Requires(0 == patterns.Length % numOfNeighbours);
            Contract.Requires(numOfNeighbours == states.Length);
            Contract.Ensures(Tools.Math.DecimalToBase(ulong.MaxValue, stateSpace).Length >=
                             Contract.Result<int[]>().Length);
            var digits = Tools.Math.DecimalToBase(ulong.MaxValue, stateSpace).Length;
            int[] code = new int[digits];
            for (int i = 0; i < patterns.Length / numOfNeighbours; i++) {
                int[] pattern = (from x in patterns
                                     .Skip(i * (int) numOfNeighbours)
                                     .Take((int) numOfNeighbours)
                                 select x).ToArray();
                var digit = (int) Tools.Math.BaseToDecimal(pattern, stateSpace);
                code[digit] = states[i];
            }
            return code;
        }

        /// <summary>
        /// Creates a Wolfram Automaton (one-dimensional)
        /// </summary>
        /// <param name="viewedSize">view-grid size</param>
        /// <param name="ruleNumber">The rule number (wolfram code) to be used: 0-255</param>
        /// <param name="stateSpace">size of the state space, 2 = binary</param>
        /// <returns></returns>
        public static CellularAutomaton NewWolframAutomaton(uint viewedSize, uint ruleNumber, uint stateSpace = 2u) {
            Contract.Requires(3 <= viewedSize);
            Contract.Requires(2 <= stateSpace);
            Contract.Requires(256 > ruleNumber);
            Rule wolframRule = NewWolframRule(WolframCode(ruleNumber));
            return new WolframAutomaton(wolframRule, (int) stateSpace, viewedSize);
        }

        /// <summary>
        /// Creates a Wolfram Automaton (one-dimensional) instance, based on the given patterns and corresponding states.
        /// </summary>
        /// <param name="viewedSize">view-grid size</param>
        /// <param name="patterns">the patterns of the rule concatenated into one array</param>
        /// <param name="states">the states correlating to each of the patterns</param>
        /// <param name="numOfNeighbours">size of the neighbourhood</param>
        /// <param name="stateSpace">size of the state space, 2 = binary</param>
        /// <returns></returns>
        public static CellularAutomaton NewWolframAutomaton(uint viewedSize, int[] patterns, int[] states, uint numOfNeighbours = 3u,
                                                            uint stateSpace = 2u) {
            Contract.Requires(3 <= viewedSize);
            Contract.Requires(1 < stateSpace);
            var wolframCode = WolframCode(patterns, states, numOfNeighbours, stateSpace);
            Rule wolframRule = NewWolframRule(wolframCode);
            return new WolframAutomaton(wolframRule, (int) stateSpace, viewedSize);
        }

        /// <summary>
        /// Get a new pattern-rule-based automaton instance, based on the given patterns and corresponding states, 
        /// for a two-dimensional CA
        /// </summary>
        /// <param name="size"></param>
        /// <param name="patterns">the patterns of the rule concatenated into one array</param>
        /// <param name="states">the states correlating to each of the patterns</param>
        /// <param name="numOfNeighbours">size of the neighbourhood</param>
        /// <param name="stateSpace"></param>
        /// <returns></returns>
        public static CellularAutomaton NewPatternAutomaton(uint size, int[] patterns, int[] states, uint numOfNeighbours = 3u,
                                                            uint stateSpace = 2u) {
            Contract.Requires(3 <= size);
            Contract.Requires(1 < stateSpace);
            var wolframCode = WolframCode(patterns, states, numOfNeighbours, stateSpace);
            Rule wolframRule = NewWolframRule(wolframCode);
            return new CellularAutomaton(1, size, wolframRule);
        }

        /// <summary>
        /// Get a new Wolfram Rule instance (for one-dimensional use).
        /// </summary>
        /// <param name="wolframCode"></param>
        /// <param name="stateSpace">MUST be >= 2</param>
        /// <returns>Wolfram CA</returns>
        public static Rule NewWolframRule(int[] wolframCode, uint stateSpace = 2u) {
            Contract.Requires(null != wolframCode);
            Contract.Requires(1 < stateSpace);
            WolframRule wolframRule = new WolframRule(1, WolframRule, wolframCode);

            // Setup the coordinates for the neighbours which the rule uses 
            var neighbourhood = new[] {-1, 0, 1};
            foreach (int n in neighbourhood) wolframRule.AddNeighbour(n);
            return wolframRule;
        }

        /// <summary>
        /// Get a new WolframRule instance - for two-dimensional pattern-based CA).
        /// </summary>
        /// <param name="wolframCode"></param>
        /// <param name="stateSpace">MUST be >= 2</param>
        /// <returns>Wolfram CA</returns>
        [PexMethod]
        public static Rule NewPatternRule(int[] wolframCode, uint stateSpace = 2u) ]]></source>
</chunk>
<method name="NewPatternRule" namespace="AutomaTones.Model.Automaton_Model.RuleLib" type="AutomaTones.Model.Automaton_Model.RuleLib.WolframAutomata" typeName="WolframAutomata" token="6000090" module="AutomaTones.exe"><hits><hit index="0" value="1"/>
<hit index="1" value="1"/>
<hit index="3" value="1"/>
<hit index="4" value="1"/>
<hit index="6" value="1"/>
<hit index="8" value="1"/>
<hit index="9" value="1"/>
<hit index="11" value="1"/>
<hit index="12" value="1"/>
<hit index="13" value="1"/>
<hit index="14" value="1"/>
<hit index="15" value="1"/>
<hit index="16" value="1"/>
<hit index="17" value="1"/>
<hit index="18" value="1"/>
<hit index="19" value="1"/>
<hit index="20" value="1"/>
<hit index="21" value="1"/>
<hit index="22" value="1"/>
<hit index="24" value="1"/>
<hit index="25" value="1"/>
<hit index="26" value="1"/>
<hit index="27" value="1"/>
<hit index="28" value="1"/>
<hit index="29" value="1"/>
<hit index="30" value="1"/>
<hit index="31" value="1"/>
<hit index="32" value="1"/>
<hit index="34" value="1"/>
<hit index="35" value="1"/>
<hit index="36" value="1"/>
<hit index="37" value="1"/>
<hit index="38" value="1"/>
<hit index="39" value="1"/>
<hit index="40" value="1"/>
<hit index="41" value="1"/>
<hit index="42" value="1"/>
<hit index="43" value="1"/>
<hit index="44" value="1"/>
<hit index="45" value="1"/>
<hit index="47" value="1"/>
<hit index="48" value="1"/>
<hit index="49" value="1"/>
<hit index="50" value="1"/>
<hit index="51" value="1"/>
<hit index="52" value="1"/>
<hit index="53" value="1"/>
<hit index="54" value="1"/>
<hit index="55" value="1"/>
<hit index="57" value="1"/>
<hit index="58" value="1"/>
<hit index="59" value="1"/>
<hit index="60" value="1"/>
<hit index="61" value="1"/>
<hit index="62" value="1"/>
<hit index="63" value="1"/>
<hit index="64" value="1"/>
<hit index="65" value="1"/>
<hit index="66" value="1"/>
<hit index="67" value="1"/>
<hit index="68" value="1"/>
<hit index="70" value="1"/>
<hit index="71" value="1"/>
<hit index="72" value="1"/>
<hit index="73" value="1"/>
<hit index="74" value="1"/>
<hit index="75" value="1"/>
<hit index="76" value="1"/>
<hit index="77" value="1"/>
<hit index="78" value="1"/>
<hit index="80" value="1"/>
<hit index="81" value="1"/>
<hit index="82" value="1"/>
<hit index="83" value="1"/>
<hit index="84" value="1"/>
<hit index="85" value="1"/>
<hit index="86" value="1"/>
<hit index="87" value="1"/>
<hit index="88" value="1"/>
<hit index="89" value="1"/>
<hit index="90" value="1"/>
<hit index="91" value="1"/>
<hit index="93" value="1"/>
<hit index="94" value="1"/>
<hit index="95" value="1"/>
<hit index="96" value="1"/>
<hit index="97" value="1"/>
<hit index="98" value="1"/>
<hit index="99" value="1"/>
<hit index="100" value="1"/>
<hit index="101" value="1"/>
<hit index="102" value="8"/>
<hit index="103" value="8"/>
<hit index="104" value="8"/>
<hit index="105" value="8"/>
<hit index="106" value="8"/>
<hit index="107" value="16"/>
<hit index="108" value="9"/>
<hit index="109" value="1"/>
<hit index="110" value="8"/>
</hits>
<coverage domain="userortestcode" unit="block" covered="6" total="6" coveredRatio="1"/>
</method>
<chunk hits="1" offset="0000" domain="userortestcode"><source><![CDATA[{]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[
            Contract.Requires(null != wolframCode);
            Contract.Requires(1 < stateSpace);
            ]]></source>
</chunk>
<chunk hits="1" offset="0001" domain="userortestcode"><source><![CDATA[WolframRule wolframRule = new WolframRule(2, WolframRule, wolframCode);]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[

            // Setup the coordinates for the neighbours which the rule uses 
            ]]></source>
</chunk>
<chunk hits="1" offset="0015" domain="userortestcode"><source><![CDATA[var neighbourhood = new[] {
                                          new[] {-1, 1}, new[] {0, 1}, new[] {1, 1}, new[] {1, 0},
                                          new[] {1, -1}, new[] {0, -1}, new[] {-1, -1}, new[] {-1, 0}
                                      };]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[
            ]]></source>
</chunk>
<chunk hits="4" offset="00cc" domain="userortestcode"><source><![CDATA[foreach]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[ (]]></source>
</chunk>
<chunk hits="8" offset="00d5" domain="userortestcode"><source><![CDATA[var n]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[ ]]></source>
</chunk>
<chunk hits="28" offset="00e9" domain="userortestcode"><source><![CDATA[in]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[ ]]></source>
</chunk>
<chunk hits="4" offset="00cd" domain="userortestcode"><source><![CDATA[neighbourhood]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[) ]]></source>
</chunk>
<chunk hits="16" offset="00db" domain="userortestcode"><source><![CDATA[wolframRule.AddNeighbour(n);]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[
            ]]></source>
</chunk>
<chunk hits="1" offset="00f7" domain="userortestcode"><source><![CDATA[return wolframRule;]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[
        ]]></source>
</chunk>
<chunk hits="1" offset="00fb" domain="userortestcode"><source><![CDATA[}]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[

        /// <summary>
        /// Demo game Wolfram automaton in the console.
        /// Press a key + return to evolve.
        /// </summary>
        [PexMethod]
        public static void WolframDemo(uint rule, int generations) {
            CellularAutomaton wolframAutomaton = NewWolframAutomaton(70, rule);
//            wolframAutomaton[35] = 1;
            Console.WriteLine("Wolfram elementary automaton using Rule "+rule);
            while (generations-- > 0) {
                Console.Write(wolframAutomaton);
                wolframAutomaton.Evolve();
            }
                Console.Read();
        }
    }
}]]></source>
</chunk>
</document>
<document src="C:\Users\Anders\Documents\automatones\Visual Studio\AutomaTones\AutomaTones\Model\Automaton Model\Rule.cs" renderPrefix="s1"><chunk hits="-1" domain="unknown"><source><![CDATA[using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using Microsoft.Pex.Framework;

namespace AutomaTones.Model.Automaton_Model {
    /// <author>Anders Øland / anoe@itu.dk</author>
    /// <summary>
    ///   A rule defining how a cell evolves.
    ///   The rule decides a cells next state based on the current state of its neighbours.
    ///   Each rule defines its own neighbourhood.
    ///   The processing is done by a RuleDelegate (which may be a multicast delegate).
    /// </summary>
    [PexClass]
    [Serializable]
    public class Rule {
        /// <summary>
        ///   The number of dimensions this rule work in; MUST match the dimensions of the automaton.
        /// </summary>
        protected internal uint Dimensions { get; private set; }

        /// <summary>
        ///   The delegate type used for the methods which perform the actual rule processing.
        /// </summary>
        /// <param name = "cell">The cell to be processed</param>
        /// <param name="statesOfNeighbours">The states of the cells neighbours</param>
        /// <param name="optional">optional parameters for specialized rules</param>
        /// <returns></returns>
        public delegate int RuleDelegate(
            Cell cell, ref IEnumerable<StateAtCoordinate> statesOfNeighbours, params int[] optional);

        /// <summary>
        ///   The concrete RuleDelagate used by this Rule to process the next state of a cell
        ///   based on the states of the cells in its neighbourghood.
        /// </summary>
        public RuleDelegate MyRuleDelegate { get; set; }

        ]]></source>
</chunk>
<method name=".ctor" namespace="AutomaTones.Model.Automaton_Model" type="AutomaTones.Model.Automaton_Model.Rule" typeName="Rule" token="60000a1" module="AutomaTones.exe"><hits><hit index="0" value="1"/>
<hit index="1" value="1"/>
<hit index="3" value="1"/>
<hit index="4" value="1"/>
<hit index="5" value="1"/>
<hit index="6" value="1"/>
<hit index="7" value="1"/>
<hit index="8" value="1"/>
<hit index="9" value="1"/>
<hit index="10" value="1"/>
<hit index="11" value="1"/>
</hits>
<coverage domain="userortestcode" unit="block" covered="5" total="5" coveredRatio="1"/>
</method>
<chunk hits="1" offset="0000" domain="userortestcode"><source><![CDATA[private List<Position> _neighbourhood = new List<Position>();]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[

        /// <summary>
        ///   The coordinates of the neighbouring cells to be used when this rule is applied.
        ///   Subject cell is always [0 ,0] (in a 2-dim. grid.) and eg. the left neighbnour is [-1, 0]
        /// </summary>
        public List<Position> Neighbourhood {
            get { return _neighbourhood; }
            protected internal set {
                Contract.Requires(null != value);
                Contract.Requires(Contract.ForAll<Position>(value, n => Dimensions == n.Coord.Length));
                Contract.Ensures(Neighbourhood == value);
                _neighbourhood = value;
            }
        }

        /// <summary>
        ///   For storing coordinates of (neighbouring) cells.
        ///   Explicit conversions to and from int[] are supported.
        /// </summary>
        [Serializable]
        public struct Position {
            private int[] _coord;

            public int[] Coord {
                get { return _coord; }
                internal set ]]></source>
</chunk>
<method name="set_Coord" namespace="AutomaTones.Model.Automaton_Model" type="AutomaTones.Model.Automaton_Model.Rule+Position" typeName="Rule+Position" token="60000ac" module="AutomaTones.exe"><hits><hit index="0" value="8"/>
<hit index="1" value="8"/>
<hit index="2" value="8"/>
</hits>
<coverage domain="userortestcode" unit="block" covered="1" total="1" coveredRatio="1"/>
</method>
<chunk hits="8" offset="0000" domain="userortestcode"><source><![CDATA[{]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[
                    Contract.Requires(null != value);
                    Contract.Requires(0 < value.Length);
                    Contract.Ensures(_coord.Equals(value));
                    ]]></source>
</chunk>
<chunk hits="8" offset="0001" domain="userortestcode"><source><![CDATA[_coord = value;]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[
                ]]></source>
</chunk>
<chunk hits="16" offset="0008" domain="userortestcode"><source><![CDATA[}]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[
            }

            public Position(params int[] coord)
                : this() {
                Contract.Requires(null != coord);
                Contract.Requires(0 < coord.Length);
                Contract.Ensures(null != coord & this.Coord == coord);
                Coord = coord;
            }

            // explicit conversion from Position to int[], useful for clients.
            public static explicit operator int[](Position p) {
                Contract.Requires(null != p.Coord);
                Contract.Ensures(Contract.ForAll(0, p.Coord.Length,
                                                 i => p.Coord[i] == Contract.Result<int[]>()[i]));
                return p.Coord.ToArray();
            }

            // explicit conversion from int[] to Position, useful for clients.
            public static explicit operator Position(int[] c) ]]></source>
</chunk>
<method name="op_Explicit" namespace="AutomaTones.Model.Automaton_Model" type="AutomaTones.Model.Automaton_Model.Rule+Position" typeName="Rule+Position" token="60000af" module="AutomaTones.exe"><hits><hit index="0" value="8"/>
<hit index="1" value="8"/>
<hit index="2" value="8"/>
<hit index="3" value="8"/>
<hit index="4" value="8"/>
<hit index="5" value="8"/>
</hits>
<coverage domain="userortestcode" unit="block" covered="2" total="2" coveredRatio="1"/>
</method>
<chunk hits="8" offset="0000" domain="userortestcode"><source><![CDATA[{]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[
                Contract.Requires(null != c);
                Contract.Requires(0 < c.Length);
                Contract.Ensures(Contract.ForAll(0, c.Length,
                                                 i => c[i] == Contract.Result<Position>().Coord[i]));
                ]]></source>
</chunk>
<chunk hits="8" offset="0001" domain="userortestcode"><source><![CDATA[return new Position { Coord = (int[])c.Clone() };]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[
            ]]></source>
</chunk>
<chunk hits="8" offset="0020" domain="userortestcode"><source><![CDATA[}]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[

            /// <summary>
            /// Pracical + operator when deciding actual coordinates of neighbours 
            /// (relative to the subject/center cell) 
            /// </summary>
            /// <param name="left"></param>
            /// <param name="right"></param>
            /// <returns></returns>
            public static int[] operator +(Position left, int[] right) {
                Contract.Requires(left.Coord.Length == right.Length);
                int[] result = new int[left.Coord.Length];
                for (int i = 0; i < right.Length; i++)
                    result[i] = right[i] + left.Coord[i];
                return result;
            }

            /// <summary>
            ///   Indicates whether this instance and a specified object are equal.
            ///   Accepts int[] as well as Position.
            /// </summary>
            /// <returns>
            ///   true if <paramref name = "obj" /> is either Position or int[] and represent the same coordinate; otherwise, false.
            /// </returns>
            /// <param name = "obj">Another object to compare to. </param>
            /// <filterpriority>2</filterpriority>
            public override bool Equals(object obj) {
                Contract.Requires(null != obj);
                Contract.Requires((obj is Position & ((Position)obj).Coord.Length > 0 || (obj is int[] & ((int[])obj).Length > 0)));
                if (!(obj is Position || obj is int[])) return false;
                Position p;
                if (obj is Position) p = (Position)obj;
                else {
                    int[] tmp = (int[])obj;
                    p = (Position)tmp;
                }
                return p.Coord.SequenceEqual(_coord);
            }

            public override int GetHashCode() {
                return (_coord != null ? _coord.GetHashCode() : 0);
            }
        }

        /// <summary>
        /// A state associated with a given coordinate. Intended for use with neighbours and rules.
        /// Thus the coordinate must be relative to point [0,0.., 0] 
        /// </summary>
        public struct StateAtCoordinate {
            [NonSerialized]
            private Position _position;

            // ReSharper disable MemberHidesStaticFromOuterClass
            public Position Position {
                // ReSharper restore MemberHidesStaticFromOuterClass
                get { return _position; }
                internal set {
                    Contract.Requires(0 < value.Coord.Length);
                    Contract.Ensures(_position.Equals(value));
                    _position = value;
                }
            }

            public int State { get; internal set; }

            public StateAtCoordinate(Position pos, int state)
                : this() {
                Contract.Requires(0 < pos.Coord.Length);
                Position = pos;
                State = state;
            }
        }

        /// <summary>
        ///   Construct a Rule for a celluar automaton with the given dimensions.
        /// </summary>
        /// <param name = "dimensions"></param>
        /// <param name = "ruleDelegate">The rule function</param>
        ]]></source>
</chunk>
<chunk hits="2" offset="000b" domain="userortestcode"><source><![CDATA[public Rule(uint dimensions, RuleDelegate ruleDelegate)]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[ ]]></source>
</chunk>
<chunk hits="1" offset="0012" domain="userortestcode"><source><![CDATA[{]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[
            ]]></source>
</chunk>
<chunk hits="1" offset="0013" domain="userortestcode"><source><![CDATA[Dimensions = dimensions;]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[
            ]]></source>
</chunk>
<chunk hits="1" offset="001b" domain="userortestcode"><source><![CDATA[MyRuleDelegate = ruleDelegate;]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[
        ]]></source>
</chunk>
<chunk hits="1" offset="0023" domain="userortestcode"><source><![CDATA[}]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[

        /// <summary>
        ///   Apply the method in the instance's RuleDelegate to the given cell.
        /// </summary>
        /// <param name="subject"></param>
        /// <param name = "cellularAutomaton"></param>
        /// <param name="optional">Optional parameters for specialized rules</param>
        /// <returns>The next state of the cell based on current state of its neighbourhood</returns>
        [PexMethod]
        public virtual int ApplyRule(int[] subject, CellularAutomaton cellularAutomaton, params int[] optional) {
            Contract.Requires(null != subject);
            Contract.Requires(0 < Neighbourhood.Count);
            Contract.Ensures(cellularAutomaton.GetCell(subject).State.SpaceMin <= Contract.Result<int>());
            Contract.Ensures(cellularAutomaton.GetCell(subject).State.SpaceMax >= Contract.Result<int>());
            IEnumerable<StateAtCoordinate> statesOfNeighbours =
                (from n in Neighbourhood
                 select new StateAtCoordinate {
                     Position = (Position)n.Coord,
                     State = cellularAutomaton.GetCell(n + subject).State.CurrentState
                 });
            return DispatchToDelegate(cellularAutomaton.GetCell(subject), statesOfNeighbours, optional);
        }

        /// <summary>
        /// This method provides a simple yet not perfect workaround for enforcing contracts on delegates.
        /// It simply wraps the invocation of the delegate with pre- and postconditions.
        /// The postcondition focuses on validating the immutability of the forwarded data.
        /// Primarily to ensure that if we're dealine with a multicast delegate - 
        /// none of its members screw things up for the others.
        /// </summary>
        /// <param name="cell"></param>
        /// <param name="statesOfNeighbours">Call by reference so we can check in the postcondition if it has been modified</param>
        /// <param name="optional"></param>
        /// <returns></returns>
        private int DispatchToDelegate(Cell cell, IEnumerable<StateAtCoordinate> statesOfNeighbours,
                                       params int[] optional) {
            Contract.Requires(null != cell);
            Contract.Requires(null != cell.State);
            Contract.Requires(0 < Neighbourhood.Count);
            Contract.Requires(Neighbourhood.Count == statesOfNeighbours.Count());
            Contract.Requires(Contract.ForAll(statesOfNeighbours, s => Dimensions == s.Position.Coord.Length));
            Contract.Ensures(Contract.OldValue(cell) == cell);
            Contract.Ensures(cell.State.SpaceMin <= Contract.Result<int>());
            Contract.Ensures(cell.State.SpaceMax >= Contract.Result<int>());
            return MyRuleDelegate(cell, ref statesOfNeighbours, optional);
        }

        /// <summary>
        ///   Clear the neighbourhood for this rule.
        /// </summary>
        protected internal void ClearNeighbourhood() {
            _neighbourhood = new List<Position>();
        }

        /// <summary>
        ///   Add a neighbour with the gicen coordinats to the neighbourhood.
        ///   Note: if it is already in the neighbourhood it will not be added again.
        /// </summary>
        /// <param name = "coord"></param>
        protected internal void AddNeighbour(params int[] coord) ]]></source>
</chunk>
<method name="AddNeighbour" namespace="AutomaTones.Model.Automaton_Model" type="AutomaTones.Model.Automaton_Model.Rule" typeName="Rule" token="60000a5" module="AutomaTones.exe"><hits><hit index="0" value="8"/>
<hit index="1" value="8"/>
<hit index="2" value="8"/>
<hit index="3" value="8"/>
<hit index="4" value="8"/>
<hit index="5" value="8"/>
<hit index="6" value="8"/>
<hit index="7" value="16"/>
</hits>
<coverage domain="userortestcode" unit="block" covered="3" total="3" coveredRatio="1"/>
</method>
<chunk hits="8" offset="0000" domain="userortestcode"><source><![CDATA[{]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[
            Contract.Requires(Dimensions == coord.Length);
            Contract.Ensures(Neighbourhood.Contains((Position)coord));
            ]]></source>
</chunk>
<chunk hits="8" offset="0001" domain="userortestcode"><source><![CDATA[_neighbourhood.Add((Position)coord);]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[
        ]]></source>
</chunk>
<chunk hits="24" offset="0013" domain="userortestcode"><source><![CDATA[}]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[

        [ContractInvariantMethod]
// ReSharper disable UnusedMember.Local
        private void ObjInvariant() {
// ReSharper restore UnusedMember.Local
            Contract.Invariant(0 < Dimensions);
        }
    }

    /// <author>Anders Øland / anoe@itu.dk</author>
    /// <summary>
    /// A specialized rule for use with Wolfram Automata - or other pattern-based rule-type CA's.
    /// </summary>
    [Serializable]
    public class WolframRule : Rule {
        /// <summary>
        /// The Wolfram code for this Wolfram rule.
        /// </summary>
        public int[] WolframCode { get; internal set; }

        ]]></source>
</chunk>
<method name=".ctor" namespace="AutomaTones.Model.Automaton_Model" type="AutomaTones.Model.Automaton_Model.WolframRule" typeName="WolframRule" token="60000ba" module="AutomaTones.exe"><hits><hit index="0" value="1"/>
<hit index="1" value="1"/>
<hit index="2" value="1"/>
<hit index="3" value="1"/>
<hit index="4" value="1"/>
</hits>
<coverage domain="userortestcode" unit="block" covered="3" total="3" coveredRatio="1"/>
</method>
<chunk hits="1" offset="0000" domain="userortestcode"><source><![CDATA[public WolframRule(uint dimensions, RuleDelegate ruleDelegate, int[] wolframCode)
            : base(dimensions, ruleDelegate)]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[ ]]></source>
</chunk>
<chunk hits="1" offset="0009" domain="userortestcode"><source><![CDATA[{]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[
            ]]></source>
</chunk>
<chunk hits="1" offset="000a" domain="userortestcode"><source><![CDATA[WolframCode = wolframCode;]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[
        ]]></source>
</chunk>
<chunk hits="1" offset="0012" domain="userortestcode"><source><![CDATA[}]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[

        /// <summary>
        ///   Apply the method in the instance's RuleDelegate to the given cell.
        /// </summary>
        /// <param name="subject"></param>
        /// <param name = "cellularAutomaton"></param>
        /// <param name="optional">Optional parameters for specialized rules</param>
        /// <returns>The next state of the cell based on current state of its neighbourhood</returns>
        public override int ApplyRule(int[] subject, CellularAutomaton cellularAutomaton, params int[] optional) {
            return base.ApplyRule(subject, cellularAutomaton, WolframCode);
        }
    }
}]]></source>
</chunk>
</document>
<document src="(no sources available for some parts of AutomaTones)" missing="true"><method name="set_Dimensions" type="AutomaTones.Model.Automaton_Model.Rule" token="600009c" module="AutomaTones.exe"><hits/>
<coverage domain="userortestcode" unit="block" covered="1" total="1" coveredRatio="1"/>
</method>
<method name="set_MyRuleDelegate" type="AutomaTones.Model.Automaton_Model.Rule" token="600009e" module="AutomaTones.exe"><hits/>
<coverage domain="userortestcode" unit="block" covered="1" total="1" coveredRatio="1"/>
</method>
<method name="set_WolframCode" type="AutomaTones.Model.Automaton_Model.WolframRule" token="60000b9" module="AutomaTones.exe"><hits/>
<coverage domain="userortestcode" unit="block" covered="1" total="1" coveredRatio="1"/>
</method>
</document>
</documents>
